package com.wxzhou.wangzhuan.service;

import com.wxzhou.wangzhuan.config.SysConfig;
import com.wxzhou.wangzhuan.dto.*;
import com.wxzhou.wangzhuan.entity.UserAccountWithUser;
import com.wxzhou.wangzhuan.entity.UserRealnameRelation;
import com.wxzhou.wangzhuan.exception.UserAccountException;
import com.wxzhou.wangzhuan.repository.UserAccountRepository;
import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.jboss.logging.Logger;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户账户服务、查询账户信息、查询收益明细等。
 */
@ApplicationScoped
public class UserAccountService {

    private static final Logger LOG = Logger.getLogger(UserAccountService.class);

    @Inject
    UserAccountRepository userAccountRepository;

    @Inject
    SysConfig sysConfig;

    /**
     * 分页查询用户子账号绑定记录
     *
     * @param pageRequest
     * @param currentUserInfo
     * @return
     */
    public Uni<PageResponseDto<UserIncomeRecordResponseDto>> getPageList(UserIncomeRecordRequestDto pageRequest, UserInfoDto currentUserInfo) {
        pageRequest.setUserid(currentUserInfo.getUserId());
        Uni<List<UserIncomeRecordResponseDto>> dataUni = userAccountRepository.findWithPagination(pageRequest);
        Uni<Long> countUni = userAccountRepository.countOf(pageRequest);
        return Uni.combine().all().unis(dataUni, countUni).asTuple().onItem().transform(tuple -> {
            List<UserIncomeRecordResponseDto> responseDtos = tuple.getItem1();
            Integer total = tuple.getItem2().intValue();
            return PageResponseDto.of(pageRequest.getPage(), pageRequest.getLimit(), total, responseDtos);
        });
    }

    /**
     * 获取用户账户信息统计数据
     *
     * @param currentUserInfo
     * @return
     */
    public Uni<UserAccountDashboardResponseDto> getAccountDashboardByUser(UserInfoDto currentUserInfo) {
        Uni<UserAccountWithUser> byUserId = userAccountRepository.findByUserId(currentUserInfo.getUserId());
        return byUserId.onItem().ifNull().failWith(() -> new UserAccountException("用户账户不存在"))
                .onItem().transform(userAccountWithUser -> convertToAccountDashboardDto(userAccountWithUser)).onFailure().recoverWithUni(throwable -> Uni.createFrom().failure(() -> {
            LOG.errorf(throwable,"查询用户账户信息异常:UserAccountService.getAccountDashboardByUser error！");
            return new UserAccountException("账户查询失败");
        }));
    }

    /**
     * 查询用户某支付渠道的实名信息
     *
     * @param userId
     * @return
     */
    public Uni<List<UserRealnameRelation>> findRealNameRelationByUser(Long userId) {
        return userAccountRepository.findRealNameRelationByUser(userId);
    }

    private UserAccountDashboardResponseDto convertToAccountDashboardDto(UserAccountWithUser entity) {
        UserAccountDashboardResponseDto dto = new UserAccountDashboardResponseDto();
        dto.setBalance(entity.getBalance().divide(new BigDecimal("100"), 2, RoundingMode.DOWN).multiply(new BigDecimal(sysConfig.getConvertRatio())));
        dto.setTotalAmount(entity.getTotalAmount().divide(new BigDecimal("100"), 2, RoundingMode.DOWN).multiply(new BigDecimal(sysConfig.getConvertRatio())));
        dto.setFrozenBalance(entity.getFrozenBalance().divide(new BigDecimal("100"), 2, RoundingMode.DOWN).multiply(new BigDecimal(sysConfig.getConvertRatio())));
        dto.setBalanceCny(entity.getBalance().divide(new BigDecimal("100"), 2, RoundingMode.DOWN));
        dto.setTotalAmountCny(entity.getTotalAmount().divide(new BigDecimal("100"), 2, RoundingMode.DOWN));
        dto.setFrozenBalanceCny(entity.getFrozenBalance().divide(new BigDecimal("100"), 2, RoundingMode.DOWN));
        return dto;
    }


    /**
     * 查询用户收益统计数据。
     *
     * @param pageRequest
     * @param currentUserInfo
     * @return
     */
    public Uni<Map<String, Object>> getAccountDashByDayRange(UserIncomeDashboardRequestDto pageRequest, UserInfoDto currentUserInfo) {
        pageRequest.setUserid(currentUserInfo.getUserId());
        Uni<List<UserIncomeRecordResponseDto>> dataUni = userAccountRepository.findIncomeWithPagination(pageRequest);
        Uni<Long> countUni = userAccountRepository.countIncomeOf(pageRequest);
        Uni<UserIncomeDashboardResponseDto> userIncomeDashboardResponseDtoUni = userAccountRepository.findTotalIncomeByRangeTime(pageRequest);
        return Uni.combine().all().unis(dataUni, countUni, userIncomeDashboardResponseDtoUni).asTuple().onItem().transform(tuple -> {
            List<UserIncomeRecordResponseDto> responseDtos = tuple.getItem1();
            Integer total = tuple.getItem2().intValue();
            UserIncomeDashboardResponseDto dashboardResponseDto = tuple.getItem3();
            PageResponseDto<UserIncomeRecordResponseDto> pageData = PageResponseDto.of(pageRequest.getPage(), pageRequest.getLimit(), total, responseDtos);
            HashMap<String, Object> result = new HashMap<>();
            result.put("page_data", pageData);
            result.put("dashboard", dashboardResponseDto);
            return result;
        });
    }

}
